Skip to main content

Datentyp: REFERENCE TO

Wichtig

Mit Compilerversion >= V3.3.0.0 werden Referenzen (mit 0) initialisiert.

Wichtig

Wenn eine Referenz auf einen Geräteeingang verweist, gilt der Zugriff als schreibender Zugriff. Dies führt bei der Codeerzeugung zu der Compilerwarnung ...kein gültiges Zuordnungsziel.

Beispiel: rInput REF= Input;

Wenn Sie ein Konstrukt dieser Art benötigen, müssen Sie den Eingangswert, beispielsweise rInput, zuerst auf eine Variable mit Schreibzugriff kopieren.

Eine Referenz mit dem Datentyp REFERENCE verweist implizit auf ein anderes Objekt. Die Zuweisung erfolgt mit dem Operator REF= . Beim Zugriff wird die Referenz implizit dereferenziert, und benötigt deswegen keinen speziellen Inhaltsoperator ^ wie ein Pointer.

Syntax

<identifier> : REFERENCE TO <data type> ;
<data type>: base type of the reference
Beispiel 214. Gültige Deklaration
PROGRAM PLC_PRG
VAR
    rspeA : REFERENCE TO DUT_SPECIAL;
    pspeA : POINTER TO DUT_SPECIAL;
    speB : DUT_SPECIAL;
END_VAR
rspeA REF= speB; // Reference rspeA is alias for speB. The code corresponds to pspeA := ADR(speB);
rspeA := speD; // The code corresponds to pspeA^ := speD;


Beispiel 215. Ungültige Deklarationen
ariTest : ARRAY[0..9] OF REFERENCE TO INT;
priTest : POINTER TO REFERENCE TO INT;
rriTest : REFERENCE TO REFERENCE TO INT;
rbitTest : REFERENCE TO BIT;


Ein Referenztyp darf nicht als Basistyp eines Arrays, Pointers oder einer Referenz verwendet werden. Außerdem darf eine Referenz nicht auf eine Bit-Variable verweisen. Solche Konstrukte erzeugen Compilerfehler.

Anmerkung

Die Lesbarkeit eines Programms wird erschwert, wenn gleichzeitig über einen Bezeichner und dessen Alias auf die gleiche Speicherzelle zugegriffen wird.

Beispiel: speB und rspeA

Tipp

Referenzen und Pointer auf BIT-Variablen sind ungültige Deklarationen, ebenso wie Arraykomponenten mit Basistyp BIT.

Beispiel 216. Beispiele

Wenn Referenzen mit := zugewiesen, wird immer ein Wert kopiert, egal ob die Referenz links, rechts oder auf beiden Seiten steht:

  • Ref := value schreibt den Wert value and die Stelle, auf die die Referenz verweist. In Pointerschreibweise Ref^ := value

  • value := Ref schreibt den Wert auf den die Referenz verweist nach value. In Pointerschreibweise value := Ref^

  • Ref1 := Ref2 schreibt den Wert, auf den Ref2 verweist, an die Stelle, auf die Ref1 verweist. In Pointerschreibweise Ref1^ := Ref2^

Wenn REF= verwendet wird, wird immer die Adresse übernommen und es muss eine Referenz auf der linken Seite stehen:

  • Ref REF= value: Die Referenz verweist auf value. In Pointerschreibweise Ref :=ADR(value)

  • Ref1 REF= Ref2: Ref1 verweist auf den gleichen Wert wie Ref2. In Pointerschreibweise Ref1 := Ref2

  • Value REF = Ref führt zu einem Compilefehler



Tipp

In der Deklaration verhält sich REFERENCE TO INT REF= value wie REFERENCE TO INT := value.

Vergleich von Referenz und Pointer

. Eine Referenz hat gegenüber einem Pointer folgende Vorteile:
  • Einfachere Nutzung:

    Eine Referenz kann direkt, ohne Dereferenzierung auf die Inhalte des referenzierten Objekts zugreifen.

  • Schönere und einfachere Syntax bei Übergabe von Werten:

    Aufruf eines Funktionsbausteins, der statt einem Pointer eine Referenz ohne Adressoperator übergibt

    Beispiel: fbDoIt(riInput:=iValue);

    statt: fbDoIt_1(piInput:=ADR(iValue));

  • Typsicherheit:

    Der Compiler prüft bei der Zuweisung zweier Referenzen, ob deren Basistypen übereinstimmen. Bei Pointern wird dies nicht geprüft.

Referenz auf Gültigkeit prüfen

Sie können den Operator __ISVALIDREF verwenden, um zu prüfen, ob eine Referenz auf einen gültigen Wert verweist, das heißt auf einen Wert ungleich 0.

Syntax

<boolean variable name> := __ISVALIDREF( <reference name> );

<reference name>: mit REFERENCE TO deklarierter Bezeichner

Die boolesche Variable wird TRUE, wenn die Referenz auf einen gültigen Wert zeigt, andernfalls FALSE.

PROGRAM PLC_PRG
VAR
    iAlfa : INT;
    riBravo : REFERENCE TO INT;
    riCharlie : REFERENCE TO INT;
    bIsRef_Bravo : BOOL := FALSE;
    bIsRef_Charlie : BOOL := FALSE;
END_VAR
iAlfa := iAlfa + 1;
riBravo REF= iAlfa;
riCharlie REF= 0;
bIsRef_Bravo := __ISVALIDREF(riBravo);  (* becomes TRUE, because riBravo references to iAlfa, which is non-zero *)
bIsRef_Charlie := __ISVALIDREF(riCharlie); (* becomes FALSE, because riCharlie is set to 0 *)

Tipp

Die implizite Überwachungsfunktion Checkpointer wirkt ab Compiler-Version 3.5.7.40 auf Variablen vom Typ REFERENCE TOin gleicher Weise wie auf Pointervariablen.